//-----------------------------------------------------------------------
// <copyright file="Endpoint.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.Live.Messenger
{
    using System;
    using System.ComponentModel;
    using Microsoft.Live.Core;

    /// <summary>
    /// Represents a particular endpoint of an instant messaging address.
    /// </summary>
    public sealed class Endpoint : INotifyPropertyChanged
    {
        private readonly MessengerEntity entity;
        private readonly User user;

        private IMAddress address;
        private Capabilities capabilities;
        private EndpointPresence presence;

        /// <summary>
        /// Initializes a new instance of the <see cref="Endpoint"/> class.
        /// </summary>
        internal Endpoint(MessengerEntity entity, User user)
        {
            this.entity = entity;
            this.entity.AttachEvent("PropertyChanged", this.OnPropertyChanged);

            this.user = user;
        }

        internal MessengerEntity Entity
        {
            get { return this.entity; }
        }

        /// <summary>
        /// Gets the endpoint's unique ID.
        /// </summary>
        public Guid Id
        {
            get { return this.entity.GetGuidProperty("Id"); }
        }

        /// <summary>
        /// Gets the associated instant messaging address.
        /// </summary>
        public IMAddress IMAddress
        {
            get
            {
                if (this.address == null)
                {
                    this.address = this.user.IMAddressFactory.FindOrCreate(
                        this.entity.GetProperty("IMAddress"));
                }

                return this.address;
            }
        }

        /// <summary>
        /// Gets the capabilities of the endpoint.
        /// </summary>
        public Capabilities Capabilities
        {
            get
            {
                if (this.capabilities == null)
                {
                    this.capabilities = new Capabilities(
                        this.entity.GetProperty("Capabilities"),
                        this.address);
                }
                return this.capabilities;
            }
        }

        /// <summary>
        /// Gets the presence information associated with the endpoint.
        /// </summary>
        public EndpointPresence Presence
        {
            get
            {
                if (this.presence == null)
                {
                    this.presence = new EndpointPresence(
                        this.entity.GetProperty("Presence"),
                        this);
                }
                return this.presence;
            }
        }

        /// <summary>
        /// Determines whether the other endpoint equals this one.
        /// </summary>
        /// <param name="other">The other endpoint.</param>
        /// <returns><c>true</c> if the endpoints are equal; otherwise <c>false</c>.</returns>
        public bool Equals(Endpoint other)
        {
            return (bool)this.entity.Invoke("Equals", other.Entity);
        }

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        private void OnPropertyChanged(object sender, MessengerEventArgs e)
        {
            this.OnPropertyChanged(
                new PropertyChangedEventArgs(
                    e.Entity.GetProperty<string>("PropertyChanged")));
        }

        private void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, e);
            }
        }
    }
}
